//**************************************
//            I N C L U D E
//**************************************

#include <avr/pgmspace.h>
#include "env_dev.h" // spi controller
#include "spi.h"  // spi controller
#include "rollo.h"


//**************************************
//   G L O B A L   V A R I A B L E
//**************************************


typedef struct {
	uint8_t state[MAX_OUT];  // 0 = ready    0x02 - 0xFF = in progress
	uint8_t status[MAX_OUT]; // finished or in progress
	uint8_t Output[MAX_PORT];
	uint8_t Output_Old[MAX_PORT];
	uint8_t advice[MAX_OUT];
} Status;

volatile Status status_var;


//**************************************
//   F U N C T I O N S
//**************************************


// for "rollo" io's
void set_io_rollo(uint8_t io_number,uint8_t io_number_compl)
{

	status_var.status[io_number] =  UNDEFINED; // set status to undefined
	
	if (io_number_compl != NO_PORT) // check if
	{
		status_var.status[io_number_compl] =  UNDEFINED; // set status to undefined
		if (status_var.state[io_number_compl])
		{
			status_var.state[io_number_compl]=0x00; // clear timer value			
			status_var.state[io_number]=0xFF;  // timer value for delayed start - to safe motor
		}
		else
		{
			status_var.state[io_number]=0xF0;  // timer value for instant start
		}
	}
	else
	{
		status_var.state[io_number]=0xF0;  // timer value for instant start
	}

return;
}

// for "rollo" io's
void clear_io_rollo(uint8_t io_number,uint8_t io_number_compl)
{

	status_var.status[io_number] =  UNDEFINED; // set status to undefined
	
	if (io_number_compl != NO_PORT) // check if
	{
		status_var.status[io_number_compl] =  UNDEFINED; // set status to undefined
		status_var.state[io_number_compl]  =  0x01;  // timer value for instant start
	}
	else
	{
		status_var.state[io_number] = 0x01;  // timer value for instant start
	}

return;
}



void do_advice(void)
{
uint8_t Change_Flag;
uint8_t i;


Change_Flag=FALSE;

	for (i=0;i<MAX_OUT;i++)
	{
		if (!status_var.state[i])
        {
        // do nothing - it's for speedup
        }
        else if (status_var.state[i] == 0x01) // this is the value to clear output
		{	
		  //status_var.Output[i/8] &= ~_BV(i%8); // clear
		    status_var.Output[i>>3] &= ~_BV(i & 0xF8); // clear
			status_var.state[i]--;
        }
		else if (status_var.state[i] == 0x02) // this is the value to clear output
		{					    
			status_var.status[i] =  FINISHED; // set task as finished
			status_var.state[i]--;
        }
		else if (status_var.state[i] > 0xF0) // this is the value for waiting - save the motor
        {			    
        	status_var.state[i]--;
        }
        else 
        {	
		    status_var.Output[i>>3] |=  _BV(i & 0xF8); // set
        	status_var.state[i]--;
        }                
	}

	for (i=0;i<MAX_PORT;i++)
	{
		if (status_var.Output_Old[i] != status_var.Output[i])  Change_Flag=TRUE;
	}

	if (Change_Flag)
	{
    	spi_out_io(&status_var.Output[0]); // write data 
		status_var.Output_Old[i]=status_var.Output[i]; //update old data
	}

}


uint8_t get_status_io(uint8_t io_number)
{

if (io_number != NO_PORT) return status_var.status[io_number];
else return UNDEFINED;
}
